<?php
declare (strict_types=1);

namespace app\common\model;

use think\facade\Cache;

class ProductCart extends Base
{
    protected $name = 'product_cart';


    public function product()
    {
        return $this->hasOne(Product::class, 'id', 'pid')
            ->field('id,title,price,cate_1,cate_2,icon,stock,status,is_del,freight,discount_open,vip_price,limit_num');
    }

    public function business()
    {
        return $this->hasOne(Business::class, 'id', 'business_id')
            ->field('id,title,logo,customer_tel,type,full_address');
    }

    public function spec()
    {
        return $this->hasOne(ProductSpecValue::class, 'id', 'spec_value_id')
            ->field('id,vip_price,price,icon,stock,currency,chain_bean,love_bean');
    }


    public static function getSettled($user, $id): array
    {
        try {
            if (empty($id)) {
                return ['code' => -1, 'msg' => '请选择要结算的商品'];
            }
            $business = parent::where('uid', $user->id)
                ->with('business')
                ->order('id', 'desc')
                ->whereIn('id', $id)
                ->group('business_id')
                ->field('id,business_id')->select();
            $list = [];
            //总运费
            $freightTotal = 0;
            $currencyTotal = 0;
            $chainBeanTotal = 0;
            $loveBeanTotal = 0;
            $vipIntegTotal = 0;
            $redCoinTotal = 0;
            $total = 0;
            //可抵扣账户
            $initialCurrency = $user->assets->currency;
            $initialChainBean = $user->assets->chain_bean;
            $initialLoveBean = $user->assets->love_bean;
            $initialVipInteg = $user->assets->vip_integ;
            $initialRedCoin = $user->assets->red_coin;
            $productAll = [];
            //分区标识
            $cate_1 = [];
            $cate_2 = [];
            foreach ($business as $key => $item) {
                $businessFreight = 0;
                $product = parent::where('business_id', $item->business_id)
                    ->with(['product', 'spec'])->whereIn('id', $id)
                    ->field('id,cate_1,pid,num,spec_value_id,sku_id')
                    ->select();
                $children = [];
                $productAll[$key]['business_id'] = $item->business->id;
                $productAll[$key]['business_title'] = $item->business->title;
                $productAll[$key]['business_customer_tel'] = $item->business->customer_tel;
                $productAll[$key]['business_type'] = $item->business['type'];
                $productAll[$key]['business_address'] = $item->business->full_address;
                foreach ($product as $vo) {
                    $sku_name = SpecItem::getSpecItemName($vo->sku_id);
                    if ($vo->product->status != 1 || $vo->product->is_del) {
                        return ['code' => -1, 'msg' => '商品《' . $vo->product->title . '》已下架'];
                    }
                    if ($vo->num > $vo->spec->stock) {
                        return ['code' => -1, 'msg' => '商品《' . $vo->product->title . '/ ' . $sku_name . '》库存不足'];
                    }
                    if($vo->product->limit_num > 0){
                        $buys = OrderProduct::where(['uid'=>$user->id, 'pid'=>$vo->product->id])->count();
                        $ordered = OrderTemporary::getOrderedNum($user->id, $vo->product->id);

                        if($buys + $ordered + $vo->num > $vo->product->limit_num){
                            return ['code' => -1, 'msg' => '商品《' . $vo->product->title . '/ ' . $sku_name . '》已超出限制购买数量~'];
                        }
                    }

                    $currency = $initialCurrency >= $vo->spec->currency * $vo->num ? $vo->spec->currency * $vo->num : $initialCurrency;
                    if ($currency > 0) $initialCurrency -= $currency;
                    $currencyTotal += $currency;

                    $chain_bean = $initialChainBean >= $vo->spec->chain_bean * $vo->num ? $vo->spec->chain_bean * $vo->num : $initialChainBean;
                    if ($chain_bean > 0) $initialChainBean -= $chain_bean;
                    $chainBeanTotal += $chain_bean;

                    $love_bean = $initialLoveBean >= $vo->spec->love_bean * $vo->num ? $vo->spec->love_bean * $vo->num : $initialLoveBean;
                    if ($love_bean > 0) $initialLoveBean -= $love_bean;
                    $loveBeanTotal += $love_bean;

                    $vip_integ = $initialVipInteg >= $vo->spec->vip_integ * $vo->num ? $vo->spec->vip_integ * $vo->num : $initialVipInteg;
                    if ($vip_integ > 0) $initialVipInteg -= $vip_integ;
                    $vipIntegTotal += $vip_integ;

                    $red_coin = $initialRedCoin >= $vo->spec->red_coin * $vo->num ? $vo->spec->red_coin * $vo->num : $initialRedCoin;
                    if ($red_coin > 0) $initialRedCoin -= $red_coin;
                    $redCoinTotal += $red_coin;

                    $vip_price = $user->level_id==1 && in_array($vo->product->cate_1, [1,8,13]) ?  $vo->spec->price : $vo->spec->vip_price;
                    $children[] = [
                        'pid'           => $vo->pid,
                        'title'         => $vo->product->title,
                        'icon'          => $vo->product->icon,
                        'spec_value_id' => $vo->spec_value_id,
                        'vip_price'     => $vip_price,
                        'sku_name'      => SpecItem::getSpecItemName($vo->sku_id),
                        'num'           => $vo->num,
                        'cate_1'        => $vo->product->cate_1,
                        'cate_2'        => $vo->product->cate_2,
                        'business_id'   => $item->business_id,
                        'currency'      => $currency,
                        'chain_bean'    => $chain_bean,
                        'love_bean'     => $love_bean,
                        'vip_integ'     => $vip_integ,
                        'red_coin'      => $red_coin,
                        'discount_open' => $vo->product->discount_open,
                        'discount_list' => UserProductDiscount::getDiscount($user->id, $vo->pid)
                    ];
                    $cate_1[] = $vo->cate_1;
                    $cate_2[] = $vo->product->cate_2;
                    $freightTotal += $vo->product->freight * $vo->num;
                    $businessFreight += $vo->product->freight * $vo->num;
                    $total += $vip_price * $vo->num;
                }

                $productAll[$key]['businessFreight'] = $businessFreight;
                $productAll[$key]['children'] = $children;
            }
            $list['product'] = $productAll;
            $list['total'] = $total;
            $list['freightTotal'] = $freightTotal;
            $list['currencyTotal'] = [
                'balance' => $user->assets->currency,
                'usable'  => $currencyTotal
            ];
            $list['chainBeanTotal'] = [
                'balance' => $user->assets->chain_bean,
                'usable'  => $chainBeanTotal
            ];
            $list['loveBeanTotal'] = [
                'balance' => $user->assets->love_bean,
                'usable'  => $loveBeanTotal
            ];

            $list['vipIntegTotal'] = [
                'balance' => $user->assets->vip_integ,
                'usable'  => $vipIntegTotal
            ];
            $list['redCoinTotal'] = [
                'balance' => $user->assets->red_coin,
                'usable'  => $redCoinTotal
            ];
            $list['realTotal'] = round($total + $freightTotal - $currencyTotal - $chainBeanTotal - $loveBeanTotal - $vipIntegTotal - $redCoinTotal, 2);

            $list['cate_1'] = $cate_1;
            $list['cate_2'] = $cate_2;

            return ['code' => 1, 'msg' => 'success', 'data' => $list];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }


    public static function getMyCart($user, $type): array
    {
        try {
            $business = parent::where('uid', $user->id)
                ->with('business')
                ->where('type', $type)
                ->order('id', 'desc')
                ->group('business_id')->field('id,business_id')->select();

            $list = [];
            $msg = 'success';
            foreach ($business as $key => $item) {
                $product = parent::where('business_id', $item->business_id)
                    ->with(['product', 'spec'])
                    ->where('type', $type)
                    ->where('uid', $user->id)
                    ->field('id,cate_1,pid,num,spec_value_id,sku_name,sku_id,status')
                    ->select();
                $children = [];
                $list[$key]['business'] = $item->business;
                foreach ($product as $vo) {

                    $children[] = [
                        'id'            => $vo->id,
                        'pid'           => $vo->pid,
                        'title'         => $vo->product->title,
                        'icon'          => isset($vo->spec) ? $vo->spec->icon : $vo->product->icon,
                        'spec_value_id' => $vo->spec_value_id,
                        'sku_id'        => $vo->sku_id,
                        'sku_name'      => $vo->sku_name,
                        'vip_price'     => isset($vo->spec) ? ($user->level_id==1 && in_array($vo->cate_1, [1,8,13]) ? $vo->spec->price : $vo->spec->vip_price) : $vo->product->vip_price,
                        'num'           => $vo->num,
                        'stock'         => isset($vo->spec) ? $vo->spec->stock : $vo->product->stock,
                        'status'        => $vo->status
                    ];
                }
                $list[$key]['children'] = $children;
            }
            return ['code' => 1, 'msg' => $msg, 'data' => $list];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function add($param, $user): array
    {
        try {

            $specValue = ProductSpecValue::where('id', $param['spec_value_id'])->find();
            if (empty($specValue)) {
                return ['code' => -1, 'msg' => '未查询到相关规格'];
            }
            $product = Product::where(['id' => $specValue->pid, 'status' => 1, 'is_del' => 0])
                ->field('id,cate_1,cate_2,business_id')->find();
            if (empty($product)) {
                return ['code' => -1, 'msg' => '商品不存在或已下架'];
            }
            if (!$param['num'] || $param['num'] <= 0) {
                return ['code' => -1, 'msg' => '数量错误'];
            }
            if ($product->cate_1 != 9) {
                //VIP通道只能未激活的会员购买
                if ($user->syn_level > 1 && $product->cate_1 == 1) {
                    return ['code' => -1, 'msg' => '您已是VIP或更高级别，不可购买此商品'];
                }
                if($product->cate_1 == 1 && $product->cate_2 == 14){
                    return ['code' => -1, 'msg' => '兑换专区商品不支持加入购物车'];
                }
                //如果是店主专区
                if ($product->cate_1 == 2) {
                    //如果是续约专区只有综合级别是店主以上才能购买
                    if ($product->cate_2 == 21 && $user->syn_level < 3) {
                        return ['code' => -1, 'msg' => '级别不足，不需要续约'];
                    }
                    //如果是其他专区只有店主以下的级别才能购买
                    if ($product->cate_2 != 21 && $user->syn_level > 2) {
                        return ['code' => -1, 'msg' => '您已是店主或更高级别，不可购买此商品'];
                    }
                }

                //限制某些专区不能加入购物车
                $unable = [5];
                if (in_array($product->cate_1, $unable)) {
                    return ['code' => -1, 'msg' => '此商品无法加入购物车'];
                }
                //限制，某些专区无法与其他专区一起加入购物车
                $redUnable = [
                    [6, 7], [8, 13, 10], [1], [3], [2], [4]
                ];
                $diffRedUnable = [];
                foreach ($redUnable as $key => $item) {
                    if (!in_array($product->cate_1, $item)) {
                        $diffRedUnable = array_merge($diffRedUnable, $item);
                    }
                }
                $count = parent::where('uid', $user->id)->where('type', 1)->whereIn('cate_1', $diffRedUnable)->count();
                if ($count) {
                    return ['code' => -1, 'msg' => '购物车内存在其他专区商品，无法加入购物车'];
                }
            }

            $map['uid'] = $user->id;
            $map['cate_1'] = $product->cate_1;
            $map['pid'] = $product->id;
            $map['spec_value_id'] = $specValue->id;
            $map['sku_id'] = $specValue->sku_id;
            $map['sku_name'] = SpecItem::getSpecItemName($specValue->sku_id);
            $map['business_id'] = $product->business_id;
            $map['type'] = $product->cate_1 == 9 ? 2 : 1;
            $cart = parent::where($map)->find();
            if ($cart) {
                $cart->num = $cart->num + $param['num'];
                $cart->save();
            } else {
                $map['num'] = $param['num'];
                parent::create($map);
            }
            return ['code' => 1, 'msg' => '加入购物车成功'];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function edit($param, $user): array
    {
        try {
            $msg = 'success';
            switch ($param['type']) {
                case 1://加
                    $info = parent::where('id', $param['id'])->field('id,num,spec_value_id')->find();
                    if ($info->num >= $info->spec->stock) {
                        return ['code' => -1, 'msg' => '库存不足'];
                    }
                    $info->num = $info->num + 1;
                    $info->save();
                    break;
                case 2://减
                    $info = parent::where('id', $param['id'])->field('id,num')->find();
                    if ($info->num <= 1) {
                        return ['code' => -1, 'msg' => '数量至少为1'];
                    }
                    $info->num = $info->num - 1;
                    $info->save();
                    break;
                case 3://删
                    parent::whereIn('id', $param['id'])->delete();
                    $msg = '已删除';
                    break;
                case 4://加入收藏夹
                    $list = parent::whereIn('id', $param['id'])->field('id,pid')->select();
                    foreach ($list as $item) {
                        UserCollectProduct::add($user->id, $item->pid);
                    }
                    $msg = '加入收藏夹成功';
                    break;
                default:
                    return ['code' => -1, 'msg' => '加载失败'];
            }
            return ['code' => 1, 'msg' => $msg];

        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function submit($param, $user): array
    {
        try {
            $all = [];
            foreach ($param['cart_id'] as $k => $v) {
                $all[$k] = parent::where('id', $v)->field('pid,num,cate_1')->find()->toArray();
            }
            Cache::set('tsOrder_' . $user->id, json_encode($all));
            Cache::set('tsOrderCartIds_' . $user->id, json_encode($param['cart_id']));

            return ['code' => 1, 'msg' => 'success', 'url' => url('order/index')->build()];

        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function clearCart($uid)
    {
        Cache::set('tsOrder_' . $uid, null);
        $ids = Cache::get('tsOrderCartIds_' . $uid);
        if (!empty($ids)) {
            parent::destroy(json_decode($ids, true));
        }
    }

}
